<?php
namespace Lib;
/**
 * PSR-4自动载入类
 */
class Autoloader{
	/**
	 * 定义一个数组:
	 * key为命名空间前缀,value为一个数组,每一项表示命名空间中类对应的base目录
	 * @var prefixs
	 */
	protected $prefixs=array();
	//注册自动载入函数
	public function register(){
		spl_autoload_register(array($this,'loadClass'));
	}
	//为命名空间添加一个基本的路径
	public function addNamespace($prefix,$base_dir,$prepend=false){
		//规范命名空间绑定路径
		$prefix=trim($prefix,'\\')."\\";
		$base_dir=rtrim($base_dir,DIRECTORY_SEPARATOR);
		//如果数组中的键值没有设置,会返回一个null在使用unshift和push时会出错的.
		if(isset($this->prefixs[$prefix])===false){
			$this->prefixs[$prefix]=array();
		}
		//判断第三个参数是前置插入还是后置插入
		if($prepend){
			array_unshift($this->prefixs[$prefix],$base_dir);
		}else{
			array_push($this->prefixs[$prefix],$base_dir);
		}
	}
	/**
	 * 自动载入函数
	 * @param  [type] $class [获取实例化的类名]
	 * 根据传入的类名,分离出命名空间和类名
	 */
	public function loadClass($class){
		if(false!==$positon=strpos($class,'\\')){
			$relative_class=substr($class,$positon+1);
			$relative_class=ucfirst($relative_class);
			$prefix=substr($class,0,$positon+1);
			$mapped_file=$this->loadMappendFile($prefix,$relative_class);
		}
	}
	//根据 命名空间前缀和类名,依据prefixs数组,映射得到实际的文件路径
	protected function loadMappendFile($prefix,$relative_class){
		//先判断数组是否存在,如果不存在就不进行下面的遍历.
		if(isset($this->prefixs[$prefix])===false){
			return false;
		}
		// 遍历成员属性数组中的相应目录,组成具体的实际目录
		foreach ($this->prefixs[$prefix] as $base_dir) {
			$file=$base_dir.str_replace('\\','/',$relative_class).".class.php";
			if($this->requireFile($file)){
				return $file;
			}
		}
	}
	//载入文件
	protected function requireFile($file){
		if(file_exists($file)){
			require $file;
			return true;
		}
		return false;
	}
}

/**
 * 类的使用范例
 * $load=new \Lib\Autoloader;
 * $load->register();
 * $load->addNamespace('Foo\Bar','/path/src');
 * $load->addNamespace('Foo\Bar','/path/test');
 */